package com.webex.ta.hydra.core;

import com.thoughtworks.xstream.annotations.XStreamAlias;

import java.util.Enumeration;
import java.util.Stack;
import java.util.Vector;

/**
 * Created by Cisco WebEx.
 * User: vegaz
 * Date: 2010-8-19
 * Time: 13:04:44
 */
@XStreamAlias("TestPlan")
public class TestPlan {

    private Command root;


    public void setRoot(Command root) {
        this.root = root;
    }

    public Command getRoot() {
        return root;
    }

    public Enumeration<Command> preorderEnumeration() {
        return new PreorderEnumeration(root);
    }


    public Command next() {
        if (root.getRuntime() != null && root.getRuntime() instanceof Controller)
            return ((Controller) root.getRuntime()).next();
        return null;
    }

    @Override
    public TestPlan clone() {
        TestPlan cloned = new TestPlan();
        cloned.root = root.clone();
        return cloned;
    }


    public boolean isEqualWith(TestPlan tp) {
        if (tp == null)
            return false;
        return root.isEqualWith(tp.root);
    }

    class PreorderEnumeration implements Enumeration<Command> {
        protected Stack stack;

        public PreorderEnumeration(Command root) {
            Vector<Command> v = new Vector<Command>(1);
            v.addElement(root);    // PENDING: don't really need a vector
            stack = new Stack<Command>();
            stack.push(v.elements());
        }

        public boolean hasMoreElements() {
            return (!stack.empty() &&
                    ((Enumeration) stack.peek()).hasMoreElements());
        }

        public Command nextElement() {
            Enumeration enumer = (Enumeration) stack.peek();
            Command node = (Command) enumer.nextElement();
            Enumeration children = node.children();

            if (!enumer.hasMoreElements()) {
                stack.pop();
            }
            if (children.hasMoreElements()) {
                stack.push(children);
            }
            return node;
        }
    }
}
